﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;



using Microsoft.Xna.Framework;

using FXnaEngine.Graphics;

using Microsoft.Xna.Framework.Graphics;



namespace FXnaEngine
{


   public class FRoadBack:FMeshProvider
    {

       public FRoadBack(FTrackLine trackLine)
       {


           this.trackLine = trackLine;


       }

       FTrackLine trackLine;

       #region Constants
       /// <summary>
       /// Factor for streching the width of the road back texture, smaller
       /// values will strech the texture more. 1.0f means we use the same as
       /// the road, which is defined in    TrackVertex.RoadWidthScale.
       /// </summary>
       const float RoadBackHullTextureWidthFactor = 1.0f;

       /// <summary>
       /// Factor for streching the width of the road tunnel texture, smaller
       /// values will strech the texture more. 1.0f means we use the same as
       /// the road, which is defined in    TrackVertex.RoadWidthScale.
       /// </summary>
       const float RoadTunnelTextureWidthFactor = 0.25f;

       /// <summary>
       /// Factor for texels we use from the roadBack texture for the sides.
       /// Most of the texture is used for the back side, but the sides
       /// are also at the top and bottom of the texture, use this factor
       /// to find out how much it is in the texture.
       /// </summary>
       const float RoadBackSideTextureHeight = 0.135f;

       /// <summary>
       /// Same as RoadBackSideTextureHeight, but we have more space for
       /// the sides in the tunnel texture!
       /// </summary>
       const float RoadTunnelSideTextureHeight = 0.235f;

       /// <summary>
       /// Palm and latern gap for the autogeneration.
       /// </summary>
       const float PalmAndLaternGap = 20.0f;

       /// <summary>
       /// Put a checkpoint every 500m
       /// </summary>
       const float CheckpointGap = 500.0f;

       /// <summary>
       /// Gap for signs, don't put them closer than this together.
       /// </summary>
       const float SignGap = 24;
       #endregion


       public override void BuildMesh()
       {
          


           #region Generate the road back vertices


           TangentVertex[] roadBackVertices;

           // We need 4 vertices per cross-section edge of the road back hull
           roadBackVertices = new TangentVertex[trackLine.Points.Count * 4];

           for (int num = 0; num < trackLine.Points.Count; num++)
           {
               // Left side of the road
               roadBackVertices[num * 4 + 0] =
                   trackLine.Points[num].LeftTangentVertex;
               roadBackVertices[num * 4 + 0].uv = new Vector2(
                   roadBackVertices[num * 4 + 0].U * RoadBackHullTextureWidthFactor,
                   0.0f);

               // Left lower side of the road
               roadBackVertices[num * 4 + 1] =
                   trackLine.Points[num].BottomLeftSideTangentVertex;
               roadBackVertices[num * 4 + 1].uv = new Vector2(
                   roadBackVertices[num * 4 + 0].U * RoadBackHullTextureWidthFactor,
                   RoadBackSideTextureHeight);

               // Right lower side of the road
               roadBackVertices[num * 4 + 2] =
                   trackLine.Points[num].BottomRightSideTangentVertex;
               roadBackVertices[num * 4 + 2].uv = new Vector2(
                   roadBackVertices[num * 4 + 0].U * RoadBackHullTextureWidthFactor,
                   1.0f - RoadBackSideTextureHeight);

               // Right side of the road
               roadBackVertices[num * 4 + 3] =
                   trackLine.Points[num].RightTangentVertex;
               roadBackVertices[num * 4 + 3].uv = new Vector2(
                   roadBackVertices[num * 4 + 3].U * RoadBackHullTextureWidthFactor,
                   1.0f);
           }



           // Set road back vertex buffer
           // fix
           //roadBackVb = new VertexBuffer(
           //    BaseGame.Device,
           //    typeof(TangentVertex),
           //    roadBackVertices.Length,
           //    ResourceUsage.WriteOnly,
           //    ResourceManagementMode.Automatic);
           VertexBuffer roadBackVb = new VertexBuffer(
               FEngineState.Device,
               typeof(TangentVertex),
               roadBackVertices.Length,
               BufferUsage.WriteOnly);
           roadBackVb.SetData(roadBackVertices);

           // Also calculate all indices, we have 6 polygons for each segment with
           // 3 vertices each. We got 1 segment less than points because the
           // last point is duplicated (different tex coords).
           int[] backIndices = new int[(trackLine.Points.Count - 1) * 6 * 3];
           int vertexIndex = 0;
           for (int num = 0; num < trackLine.Points.Count - 1; num++)
           {
               // We only use 4 vertices (and the next 4 vertices),
               // but we have to construct all 18 indices for our 6 polygons.
               for (int sideNum = 0; sideNum < 3; sideNum++)
               {
                   // Each side needs 2 polygons.

                   // 1. Polygon
                   backIndices[num * 18 + 6 * sideNum + 0] =
                       vertexIndex + sideNum;
                   backIndices[num * 18 + 6 * sideNum + 1] =
                       vertexIndex + 5 + sideNum;
                   backIndices[num * 18 + 6 * sideNum + 2] =
                       vertexIndex + 4 + sideNum;

                   // 2. Polygon
                   backIndices[num * 18 + 6 * sideNum + 3] =
                       vertexIndex + 5 + sideNum;
                   backIndices[num * 18 + 6 * sideNum + 4] =
                       vertexIndex + sideNum;
                   backIndices[num * 18 + 6 * sideNum + 5] =
                       vertexIndex + 1 + sideNum;
               }

               // Go to the next 4 vertices
               vertexIndex += 4;
           }

           // Set road back index buffer
           // fix
           //roadBackIb = new IndexBuffer(
           //    BaseGame.Device,
           //    typeof(int),
           //    backIndices.Length,
           //    ResourceUsage.WriteOnly,
           //    ResourceManagementMode.Automatic);
           IndexBuffer roadBackIb = new IndexBuffer(
               FEngineState.Device,
               typeof(int),
               backIndices.Length,
               BufferUsage.WriteOnly);
           roadBackIb.SetData(backIndices);
           #endregion




       }


    }
}
